package tr3dtris.game.display;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import tr3dtris.game.models.CellArray;
import tr3dtris.game.models.pieces.AbstractPiece;

/**
 * 2D test implementation of the abstract dispaly class.
 * Used for playing the game with a simple 2D view (mostly used for debug)
 * @author Luciano Mammino <loige@hotmail.com>
 * @author Andrea Mangano <kapitan0@hotmail.it>
 * @version 0.1
 * @since 0.1
 */
public class Display2d extends EmptyDisplay
{
    /**
     * Size of the cell
     */
    private static final int CELLSIZE = 30;

    /**
     * Array of colors for coloring differente pieces with different colors
     */
    private static final Color[] COLORS = { Color.BLUE,
                                            Color.CYAN,
                                            Color.GREEN,
                                            Color.MAGENTA,
                                            Color.ORANGE,
                                            Color.PINK,
                                            Color.YELLOW };
    private static final Color OUTSIDE_BORDER = new Color(0,0,0,128);
    private static final Color INSIDE_BRIGHT_BORDER = new Color(255,255,255,128);
    private static final Color INSIDE_DARK_BORDER = new Color(0,0,0,70);

    /**
     * Blank contructor
     */
    public Display2d()
    {}

    /**
     * {@inheritDoc}
     */
    @Override
    public void configure()
    {}

    /**
     * {@inheritDoc}
     */
    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        //g.clearRect(0, 0, this.getWidth(), this.getHeight());

        //select game message
        String message = "";
        if(this.game.isGameOver())
            message = "Game over! To start a new game press 'R'";
        if(this.game.isPlaying())
            message = "press 'p' to pause the game or 'r' to begin a new game";
        if(this.game.isPaused())
            message = "Game paused. Press 'p' to restart or 'r' to begin a new game";
        if(!this.game.isPlaying() && !this.game.isGameOver() && !this.game.isPaused())
            message = "Press 'ENTER' to start!";

        CellArray grid = game.getGrid();
        g.setFont(new Font("Arial", Font.PLAIN, 12));
        g.drawString("treDtris 2d game. " + message, 10, 10);
        g.drawString("Points: " + this.game.getPoints(), 30, 50);
        g.drawString("Lines erased: " + this.game.getLinesErased(), 30, 70);
        int width = grid.getWidth() * CELLSIZE;
        int height = grid.getHeight() * CELLSIZE;
        Point origin = new Point((int)((this.getWidth() - width)/2), (int)((this.getHeight() - height)/2));

        //draw borders
        g.drawLine(origin.x - 1, origin.y, origin.x - 1, origin.y + height);
        g.drawLine(origin.x + width, origin.y, origin.x + width, origin.y + height);
        g.drawLine(origin.x, origin.y + height, origin.x + width, origin.y + height);


        if(this.game.isPaused())
        {
            g.setColor(Color.BLACK);
            g.setFont(new Font("Arial", Font.PLAIN, 32));
            g.drawString("PAUSED", this.getWidth()/2, this.getHeight()/2);
        }
        else
        {
            //draw cells
            for(int x = 0; x < grid.getWidth(); x++)
            {
                for(int y=0; y < grid.getHeight(); y++)
                {
                    if(grid.hasBlockAt(x, y))
                    {
                        this.paintBlock(g, origin.x + x*CELLSIZE, origin.y + y*CELLSIZE, grid.getBlockAt(x, y).getType()-1);
                    }
                }
            }

            //draw active piece
            if(game.getCurrentPiece() != null)
            {
                AbstractPiece cPiece = game.getCurrentPiece();
                g.setColor(COLORS[cPiece.getTypeId()-1]);
                for(int x=0; x < cPiece.getWidth(); x++)
                {
                    for (int y=0; y < cPiece.getHeight(); y++)
                    {
                        int posX = cPiece.getX();
                        int posY = cPiece.getY();
                        if(cPiece.getCells().hasBlockAt(x, y))
                            this.paintBlock(g, origin.x + (x + posX)*CELLSIZE, origin.y + (y + posY)*CELLSIZE, cPiece.getTypeId()-1);
                    }
                }
            }

            //draw next piece
            Point np = new Point(10, this.getWidth()/2);
            AbstractPiece cp = this.game.getNextPiece();
            if(cp != null)
            {
                for(int x=0; x < cp.getCells().getWidth(); x++)
                {
                    for(int y=0; y < cp.getCells().getHeight(); y++)
                    {
                        if(cp.getCells().hasBlockAt(x, y))
                        {
                            this.paintBlock(g, np.x + x*CELLSIZE, np.y + y*CELLSIZE, cp.getTypeId()-1);
                        }
                    }
                }
            }
        }

        if(this.game.isGameOver())
        {
            g.setColor(Color.BLACK);
            g.setFont(new Font("Arial", Font.PLAIN, 32));
            g.drawString("GAME OVER", this.getWidth()/2, this.getHeight()/2);
        }

    }

    private void paintBlock(Graphics g, int x, int y, int color)
    {
        g.setColor(COLORS[color]);
        g.fillRect(x, y, CELLSIZE, CELLSIZE);
        g.setColor(OUTSIDE_BORDER);
        g.drawRect(x, y, CELLSIZE, CELLSIZE);
        g.setColor(INSIDE_DARK_BORDER);
        g.drawLine(x + 1, y + 1, x + CELLSIZE - 1, y + 1);
        g.drawLine(x + CELLSIZE - 1, y + 1, x + CELLSIZE - 1, y + CELLSIZE - 1);
        g.setColor(INSIDE_BRIGHT_BORDER);
        g.drawLine(x + 1, y + 2, x + 1, y + CELLSIZE - 2);
        g.drawLine(x + 1, y + CELLSIZE - 1, x + CELLSIZE - 1, y + CELLSIZE - 1);
    }

    /**
     * {@inheritDoc}
     */
    public void refresh()
    {
        this.repaint();
    }
}